home *** CD-ROM | disk | FTP | other *** search
/ Gekkan Dennou Club 147 / Gekkan Dennou Club - 2000.8 Vol. 147 (Japan).7z / Gekkan Dennou Club - 2000.8 Vol. 147 (Japan) (Track 1).bin / games / ippon / source.lzh / FuncEnemy / lboss01.c < prev    next >
C/C++ Source or Header  |  2000-07-07  |  17KB  |  647 lines

  1. /* lboss01.c 1面ボス */
  2. #include <xsp2lib.h>
  3.  
  4. #include "../main.h"
  5. #include "../player.h"
  6. #include "../shot.h"
  7. #include "../enemy.h"
  8. #include "../eshot.h"
  9. #include "../effect.h"
  10. #include "../psearch.h"
  11. #include "../sound.h"
  12.  
  13. #ifdef DEBUG
  14. #include <stdio.h>
  15. #include "../txfont.h"
  16. #endif
  17.  
  18. #define PALET_MAIN    0x0700
  19.  
  20. #define SPEED_LASER        30
  21.  
  22. #define SPEED_1        3    /* 加速度 */
  23. #define SPEED_1N    28    /* 加速度を足す回数 */
  24.  
  25. #define SPEED_SHOT1    8    /* 1段階目扇型ショット速度 */
  26. #define SPEED_SHOT2    10    /* 2段階目伸びるショットの一番遅い弾の速度 */
  27. #define SPEED_SHOT3    12    /* 2段階目なぎ倒し弾の速度 */
  28.  
  29. #define HP_0    1800        /* 耐久力 */
  30. #define HP_1    1000        /* 耐久力がこれ以下になったら2段階目へ */
  31. #define HP_2    500        /* 耐久力がこれ以下になったら3段階目へ */
  32. #define TIMER_1    2500        /* これ以上時間が経過したら2段階目へ */
  33. #define TIMER_2    4000        /* これ以上時間が経過したら3段階目へ */
  34. #define TIMER_3    6000        /* これ以上時間が経過したら撤退 */
  35.  
  36. #define TIME_SHOT_ERASE    50    /* 耐久力がこれだけ減るごとにショットを抜く */
  37.  
  38. #define SPEED_3        3    /* 3段階目(撤退)の加速度 */
  39. #define SPEED_3N    32    /* 3段階目の加速度を足す回数 */
  40.  
  41. #define MOVE_DEATH    8
  42.  
  43.  
  44.  
  45. enum {
  46.     MOVETO_INIT = 0,    /* 初期状態 */
  47.     MOVETO_C2L,        /* 中央から左に移動 */
  48.     MOVETO_L2C,
  49.     MOVETO_C2R,
  50.     MOVETO_R2C
  51. };
  52.  
  53.  
  54. /* 関数プロトタイプ宣言 */
  55. static short EnemyMoveLBoss01 (ENEMY *);
  56. static void EnemyFreeLBoss01 (ENEMY *);
  57.  
  58.  
  59.  
  60. /* 初期化ルーチン */
  61. void EnemyAllocLBoss01 (ENEMY * p)
  62. {
  63.     p->vx = 0;
  64.     p->vy = -6 << 16;
  65.  
  66.     p->pt = obj_lboss01 + 1;
  67.     p->info = PALET_MAIN | PRIORITY_BOSS;
  68.     p->hit_sx = p->hit_sy = 0;    /* 当たり判定なし */
  69.     p->hp = HP_0;
  70.     p->damage = 0;
  71.     p->flash = 0;
  72.  
  73.     p->damage_mode = DAMAGE_PIERCE;
  74.     p->func_enemy_move = EnemyMoveLBoss01;
  75.     p->func_enemy_free = EnemyFreeLBoss01;
  76.  
  77.     /* コア関連 */
  78.     p->core_info = PALET_CORE_BLUE | PRIORITY_BOSS;
  79.     p->core_pt = sp_core;
  80.  
  81.     p->m_work = 0;
  82.     p->m_work5 = 0;
  83.     p->timer = 0;
  84. }
  85.  
  86.  
  87.  
  88. /* 移動ルーチン */
  89. /* 返り値:非0なら消去 */
  90. static short EnemyMoveLBoss01 (ENEMY * p)
  91. {
  92.     /* 速度を足して上位ワード(固定整数部)だけ取り出す */
  93.     p->x = (p->lx += p->vx) >> 16;
  94.     p->y = (p->ly += p->vy) >> 16;
  95.     p->timer++;
  96.  
  97. #ifdef DEBUG
  98.     {
  99.         char temp_str[32];
  100.         sprintf (temp_str, "TIMER %06d", p->timer);
  101.         TxfontCursor (20, 2);
  102.         TxfontPuts (temp_str);
  103.         sprintf (temp_str, "HP %06hd", p->hp);
  104.         TxfontCursor (20, 3);
  105.         TxfontPuts (temp_str);
  106.     }
  107. #endif
  108.     switch (p->m_work) {
  109.         /* まず上に上がってくる */
  110.     case 0:
  111.         if (SHORT_LY < 200)
  112.             p->m_work++;
  113.         break;
  114.  
  115.         /* 減速 */
  116.     case 1:
  117.         p->vy += 8192;
  118.         if (p->vy > -8192) {
  119.             p->m_work++;
  120.             p->vy = 0;
  121.             p->hit_sx = 54;        /* ここで初めて当たり判定ができる */
  122.             p->hit_sy = 16;
  123.             p->m_work2 = MOVETO_INIT;    /* 移動方向 */
  124.             p->s_work = p->s_work2 = p->s_work3 = 0;
  125.         }
  126.         break;
  127.  
  128.         /* 第1形態・左右に移動しつつ扇状弾 */
  129.     case 2:
  130.         /* まず移動処理 */
  131.         if (p->m_work2 == MOVETO_INIT) {
  132.             /* 初期状態なら */
  133.             if (p->x > player->x)
  134.                 p->m_work2 = MOVETO_C2L;    /* 移動方向 */
  135.             else
  136.                 p->m_work2 = MOVETO_C2R;    /* 移動方向 */
  137.             p->m_work3 = 0;
  138.         }
  139.         if (p->m_work3 == 0) {
  140.             /* 初回なら */
  141.             signed short dx, dy;
  142.             signed short dx_table[5] =
  143.             {0, 54 + 16, 128 + 16, 256 - 54 + 16, 128 + 16};
  144.             short m_work_table[5] =
  145.             {MOVETO_INIT, MOVETO_L2C, MOVETO_C2R, MOVETO_R2C, MOVETO_C2L};
  146.  
  147.             p->m_work3 = !0;
  148.             /* 順に左→中央→右→中央→左へ移動 */
  149.             dx = dx_table[p->m_work2];
  150.             p->m_work2 = m_work_table[p->m_work2];    /* 移動方向 */
  151.  
  152.             /* player->y は乱数の種として使用しています */
  153.             if (SHORT_LY < 80)
  154.                 dy = (((unsigned short) rndtable[(player->y) & 0xff]) / 4 + 32 + 16);
  155.             else
  156.                 dy = 64;
  157.             /* 移動方向を設定 */
  158.             SubEnemyMoveToInit (p, dx, dy, SPEED_1, SPEED_1N);
  159.         } else {
  160.             /* 設定値に従って移動 */
  161.             if (SubEnemyMoveTo (p) < 0)
  162.                 p->m_work3 = 0;        /* 移動方向再設定 */
  163.         }
  164.         /* 次に攻撃処理 */
  165.  
  166.         switch (p->s_work) {
  167.             /* なぎたおし弾 */
  168.         case 0:    /* p->s_work */
  169. #define INTERVAL_2_0    6
  170. #define SPEED_SHOT_2_0    9
  171.             switch (p->s_work2++) {
  172.             case 0:
  173.                 p->s_angle = 64 - 32;
  174.                 p->s_angle2 = 64 + 32;
  175.                 break;
  176.             case 20 + INTERVAL_2_0 * 0:
  177.                 EshotAlloc (ESHOT_NRG24N, SHORT_LX, SHORT_LY, SPEED_SHOT_2_0, p->s_angle, 3);
  178.                 EshotAlloc (ESHOT_NRG24N, SHORT_LX, SHORT_LY, SPEED_SHOT_2_0, p->s_angle2, 3);
  179.                 p->s_angle += 6;
  180.                 p->s_angle2 -= 6;
  181.                 SoundSetSE (SE_ESHOT);    /* 敵ショット音 */
  182.             case 20 + INTERVAL_2_0 * 1:
  183.             case 20 + INTERVAL_2_0 * 2:
  184.             case 20 + INTERVAL_2_0 * 3:
  185.             case 20 + INTERVAL_2_0 * 4:
  186.             case 20 + INTERVAL_2_0 * 5:
  187.             case 20 + INTERVAL_2_0 * 6:
  188.             case 20 + INTERVAL_2_0 * 7:
  189.             case 20 + INTERVAL_2_0 * 8:
  190.             case 20 + INTERVAL_2_0 * 9:
  191.             case 20 + INTERVAL_2_0 * 10:
  192.             case 20 + INTERVAL_2_0 * 11:
  193.             case 20 + INTERVAL_2_0 * 12:
  194.             case 20 + INTERVAL_2_0 * 13:
  195.                 EshotAlloc (ESHOT_NRG04, SHORT_LX, SHORT_LY, SPEED_SHOT_2_0, p->s_angle, 3);
  196.                 EshotAlloc (ESHOT_NRG04, SHORT_LX, SHORT_LY, SPEED_SHOT_2_0, p->s_angle2, 3);
  197.                 p->s_angle += 6;
  198.                 p->s_angle2 -= 6;
  199.                 SoundSetSE (SE_ESHOT);    /* 敵ショット音 */
  200.                 break;
  201.             case 20 + INTERVAL_2_0 * 15:
  202.                 p->s_work2 = 0;
  203.                 if (p->s_work3++ > 1) {
  204.                     p->s_work++;
  205.                     p->s_work3 = 0;
  206.                 }
  207.                 break;
  208.             default:
  209.                 break;
  210.             }
  211.             break;
  212.             /* V字弾 */
  213.         case 1:    /* p->s_work */
  214. #define INTERVAL_2_1    40
  215. #define SPEED_SHOT_2_1    12
  216.             switch (p->s_work2++) {
  217.             case 10 + INTERVAL_2_1 * 0:
  218.             case 10 + INTERVAL_2_1 * 1:
  219.             case 10 + INTERVAL_2_1 * 2:
  220.             case 10 + INTERVAL_2_1 * 3:
  221.             case 10 + INTERVAL_2_1 * 4:
  222.             case 10 + INTERVAL_2_1 * 5:
  223.             case 10 + INTERVAL_2_1 * 6:
  224.             case 10 + INTERVAL_2_1 * 7:
  225.             case 10 + INTERVAL_2_1 * 8:
  226.                 EshotAlloc (ESHOT_NRG02, SHORT_LX + 24, SHORT_LY - 24, SPEED_SHOT_2_1, 64 - 18, 2);
  227.                 EshotAlloc (ESHOT_NRG02, SHORT_LX - 24, SHORT_LY - 24, SPEED_SHOT_2_1, 64 + 18, 2);
  228.                 EshotAlloc (ESHOT_NRG03, SHORT_LX + 16, SHORT_LY - 12, SPEED_SHOT_2_1, 64 - 12, 2);
  229.                 EshotAlloc (ESHOT_NRG03, SHORT_LX - 16, SHORT_LY - 12, SPEED_SHOT_2_1, 64 + 12, 2);
  230.                 EshotAlloc (ESHOT_NRG04, SHORT_LX + 8, SHORT_LY, SPEED_SHOT_2_1, 64 - 6, 2);
  231.                 EshotAlloc (ESHOT_NRG04, SHORT_LX - 8, SHORT_LY, SPEED_SHOT_2_1, 64 + 6, 2);
  232.                 EshotAlloc (ESHOT_NRG05, SHORT_LX, SHORT_LY + 12, SPEED_SHOT_2_1, 64, 2);
  233.                 SoundSetSE (SE_ESHOT);    /* 敵ショット音 */
  234.                 break;
  235.             case 10 + INTERVAL_2_1 * 10:
  236.                 p->s_work++;
  237.                 p->s_work2 = 0;
  238.                 p->s_work3 = 0;
  239.                 p->s_angle = 64;
  240.                 break;
  241.             default:
  242.                 break;
  243.             }
  244.             break;
  245.             /* うずまき弾 */
  246.         case 2:    /* p->s_work */
  247.             if (p->s_work2++ > 1) {
  248.                 p->s_work2 = 0;
  249.                 if (p->s_work3++ > 120) {
  250.                     p->s_work = p->s_work2 = p->s_work3 = 0;
  251.                 }
  252. #define SPEED_SHOT_2_2    8
  253.                 EshotAlloc (ESHOT_NRG03, SHORT_LX, SHORT_LY, SPEED_SHOT_2_2, p->s_angle, 4);
  254.                 EshotAlloc (ESHOT_NRG04, SHORT_LX, SHORT_LY, SPEED_SHOT_2_2, p->s_angle + 85, 4);
  255.                 EshotAlloc (ESHOT_NRG05, SHORT_LX, SHORT_LY, SPEED_SHOT_2_2, p->s_angle + 170, 4);
  256.                 p->s_angle += 6;
  257.                 SoundSetSE (SE_ESHOT);    /* 敵ショット音 */
  258.             }
  259.             break;
  260.         default:    /* p->s_work */
  261.             p->s_work = 0;
  262.             break;
  263.         }
  264.  
  265.         /* ある程度ダメージを受けた or 時間切れ */
  266.         if ((p->hp < HP_1) || (p->timer > TIMER_1)) {
  267.             /* カバー破棄 */
  268.             EnemyAlloc (ENEMY_LBOSS01C, SHORT_LX, SHORT_LY);    /* カバーを分離 */
  269.  
  270.             if (!eshot_erase)
  271.                 eshot_erase = ESHOT_ERASE;    /* 弾消し */
  272.             p->pt++;
  273.             p->m_work++;
  274.             p->m_work2 = 0;
  275.             p->m_work3 = 0;
  276.             p->hit_sx = p->hit_sy = 0;    /* 当たり判定なし */
  277.             /* 刺さったショットの処理 */
  278.             if (p->shot)
  279.                 p->shot->status = SHOT_STATUS_NON;
  280.         }
  281.         break;
  282.  
  283.     case 3:        /* アニメーション開始! */
  284.         p->m_work3++;
  285.         switch (p->m_work2) {
  286.         case 0:
  287.             if (SubEnemyMoveTo (p) < 0)    /* 止まるまで待つ */
  288.                 p->m_work2++;
  289.             break;
  290.         case 1:
  291.             if (p->m_work3 < 100)
  292.                 break;
  293.             if (p->pt < obj_lboss01 + 50) {
  294.                 p->pt++;
  295.             } else {
  296.                 p->m_work++;
  297.                 p->m_work2 = MOVETO_INIT;    /* 移動方向 */
  298.  
  299.                 p->s_work = p->s_work2 = p->s_work3 = p->s_work4 = 0;
  300.                 p->s_angle3 = 0;
  301.  
  302.                 p->hit_sx = 70;
  303.                 p->hit_sy = 16;
  304.             }
  305.             if ((p->pt == obj_lboss01 + 9) || (p->pt == obj_lboss01 + 30) || (p->pt == obj_lboss01 + 46))
  306.                 SoundSetSE (SE_LOCK_M);        /* 「がちゃん」という効果音を鳴らす */
  307.             break;
  308.         }
  309.         break;
  310.  
  311.  
  312.         /* 第2形態 */
  313.     case 4:
  314.         /* ある程度ダメージを受けた or 時間切れ */
  315.         if ((p->hp < HP_2) || (p->timer > TIMER_2)) {
  316.             p->m_work++;    /* 時間切れ */
  317.             p->m_work2 = MOVETO_INIT;    /* 移動方向 */
  318.             p->hit_sx = p->hit_sy = 0;    /* 当たり判定なし */
  319.             EffectAlloc (EFFECT_EXPL, 0, p->x, p->y);    /* 爆発パターンを出現させる */
  320.             SoundSetSE (SE_EXPL_M);        /* 中ボス爆発音 */
  321.             if (!eshot_erase)
  322.                 eshot_erase = ESHOT_ERASE;    /* 弾消し */
  323.             /* 刺さったショットの処理 */
  324.             if (p->shot)
  325.                 p->shot->status = SHOT_STATUS_NON;
  326.             break;
  327.         }
  328.         /* まず移動処理 */
  329.         if (p->m_work2 == MOVETO_INIT) {
  330.             /* 初期状態なら */
  331.             if (p->x > player->x)
  332.                 p->m_work2 = MOVETO_C2L;    /* 移動方向 */
  333.             else
  334.                 p->m_work2 = MOVETO_C2R;    /* 移動方向 */
  335.             p->m_work3 = 0;
  336.         }
  337.         if (p->m_work3 == 0) {
  338.             /* 初回なら */
  339.             signed short dx, dy;
  340.             signed short dx_table[5] =
  341.             {0, 54 + 16, 128 + 16, 256 - 54 + 16, 128 + 16};
  342.             short m_work_table[5] =
  343.             {MOVETO_INIT, MOVETO_L2C, MOVETO_C2R, MOVETO_R2C, MOVETO_C2L};
  344.  
  345.             p->m_work3 = !0;
  346.             /* 順に左→中央→右→中央→左へ移動 */
  347.             dx = dx_table[p->m_work2];
  348.             p->m_work2 = m_work_table[p->m_work2];    /* 移動方向 */
  349.  
  350.             /* player->y は乱数の種として使用しています */
  351.             if (SHORT_LY < 80)
  352.                 dy = (((unsigned short) rndtable[(player->y) & 0xff]) / 4 + 32 + 16);
  353.             else
  354.                 dy = 64;
  355.             /* 移動方向を設定 */
  356.             SubEnemyMoveToInit (p, dx, dy, SPEED_1, SPEED_1N);
  357.         } else {
  358.             /* 設定値に従って移動 */
  359.             if (SubEnemyMoveTo (p) < 0)
  360.                 p->m_work3 = 0;        /* 移動方向再設定 */
  361.         }
  362.  
  363.  
  364.         /* 次に攻撃処理 */
  365.         switch (p->s_work) {
  366. #define INTERVAL_4    9
  367. #define SPEED_SHOT_4_0        20    /* 3ウェイ弾 */
  368. #define SPEED_SHOT_4_0_1    11    /* 円形炸裂弾 */
  369. #define SPEED_SHOT_4_0_2     6    /* 半円形炸裂弾 */
  370.         case 0:    /* p->s_work */
  371.             switch (p->s_work2++) {
  372.             case 0:
  373.                 p->s_angle = psearch (p->x, p->y);    /* 自機の方向をサーチ */
  374.                 break;
  375.             case 15 + INTERVAL_4 * 0:
  376.             case 15 + INTERVAL_4 * 1:
  377.             case 15 + INTERVAL_4 * 2:
  378.             case 15 + INTERVAL_4 * 3:
  379.                 EshotAlloc (ESHOT_NRG02, SHORT_LX, SHORT_LY, SPEED_SHOT_4_0 - 4, p->s_angle - 24, 0);
  380.                 EshotAlloc (ESHOT_NRG02, SHORT_LX, SHORT_LY, SPEED_SHOT_4_0 - 4, p->s_angle + 24, 0);
  381.                 EshotAlloc (ESHOT_NRG03, SHORT_LX, SHORT_LY, SPEED_SHOT_4_0 - 2, p->s_angle - 12, 0);
  382.                 EshotAlloc (ESHOT_NRG03, SHORT_LX, SHORT_LY, SPEED_SHOT_4_0 - 2, p->s_angle + 12, 0);
  383.                 EshotAlloc (ESHOT_NRG05, SHORT_LX, SHORT_LY, SPEED_SHOT_4_0, p->s_angle, 0);
  384.                 SoundSetSE (SE_ESHOT);    /* 敵ショット音 */
  385.                 break;
  386.             case 15 + INTERVAL_4 * 4:
  387.                 {
  388.                     short h;
  389.                     unsigned char a = 0;
  390.                     for (h = 0; h < 16; h++)
  391.                         EshotAlloc (ESHOT_NRG35, SHORT_LX, SHORT_LY, SPEED_SHOT_4_0_1, a += 16, 0);
  392.                 }
  393.                 SoundSetSE (SE_EBOMB_L);    /* 敵ショット音 */
  394.                 break;
  395.             case 15 + INTERVAL_4 * 7:
  396.                 {
  397.                     short h;
  398.                     unsigned char a = psearch (p->x, p->y) - 10 * 4;
  399.                     for (h = 0; h < 9; h++)
  400.                         EshotAlloc (ESHOT_NRG34N, SHORT_LX, SHORT_LY, SPEED_SHOT_4_0_2, a += 10, 0);
  401.                 }
  402.                 SoundSetSE (SE_EBOMB_M);    /* 敵ショット音 */
  403.                 break;
  404.             case 15 + INTERVAL_4 * 8:
  405.                 p->s_work2 = 0;
  406.                 if (p->s_work3++ > 0) {
  407.                     p->s_work++;
  408.                     p->s_work2 = p->s_work3 = 0;
  409.                 }
  410.                 break;
  411.             default:
  412.                 break;
  413.             }
  414.             break;
  415.         case 1:    /* p->s_work */
  416. #define INTERVAL_4_1    9
  417. #define SPEED_SHOT_4_1    15
  418.             if (p->s_work2++ > 1) {
  419.                 p->s_work2 = 0;
  420.                 if (p->s_work3++ > 20) {
  421.                     if (p->s_work3++ > 45) {
  422.                         p->s_work++;
  423.                         p->s_work3 = 0;
  424.                     } else {
  425.                         EshotAlloc (ESHOT_NRG04, SHORT_LX, SHORT_LY + 16, SPEED_SHOT_4_1, (rndtable[p->s_work3] & 0x3f) - 0x1f + psearch (p->x, p->y), 0);
  426.                         SoundSetSE (SE_ESHOT);    /* 敵ショット音 */
  427.                     }
  428.                 } else {
  429.                     EshotAlloc (ESHOT_NRG03, SHORT_LX, SHORT_LY + 16, SPEED_SHOT_4_1 - 4, (rndtable[p->s_work3] & 0x3f) - 0x1f + psearch (p->x, p->y), 0);
  430.                     SoundSetSE (SE_ESHOT);    /* 敵ショット音 */
  431.                 }
  432.             }
  433.             break;
  434.         case 2:    /* p->s_work */
  435.             p->s_work = 0;
  436.             break;
  437.         default:    /* p->s_work */
  438.             p->s_work = 0;
  439.             break;
  440.         }
  441.         break;
  442.  
  443.     case 5:        /* アニメーション開始! */
  444.         if (SubEnemyMoveTo (p) < 0) {    /* 止まるまで待つ */
  445.             p->m_work++;
  446.             p->m_work2 = MOVETO_INIT;    /* 移動方向 */
  447.  
  448.             p->s_work = p->s_work2 = p->s_work3 = p->s_work4 = 0;
  449.             p->hit_sx = 70;
  450.             p->hit_sy = 16;
  451.         }
  452.         break;
  453.  
  454.         /* 最後の攻撃 */
  455.     case 6:
  456.         if (p->timer > TIMER_3) {
  457.             p->m_work++;    /* 時間切れ */
  458.             p->m_work2 = 0;
  459.             break;
  460.         }
  461.         /* まず移動処理 */
  462.         if (p->m_work2 == MOVETO_INIT) {
  463.             /* 初期状態なら */
  464.             if (p->x > player->x)
  465.                 p->m_work2 = MOVETO_C2L;    /* 移動方向 */
  466.             else
  467.                 p->m_work2 = MOVETO_C2R;    /* 移動方向 */
  468.             p->m_work3 = 0;
  469.         }
  470.         if (p->m_work3 == 0) {
  471.             /* 初回なら */
  472.             signed short dx, dy;
  473.             signed short dx_table[5] =
  474.             {0, 54 + 16, 128 + 16, 256 - 54 + 16, 128 + 16};
  475.             short m_work_table[5] =
  476.             {MOVETO_INIT, MOVETO_L2C, MOVETO_C2R, MOVETO_R2C, MOVETO_C2L};
  477.  
  478.             p->m_work3 = !0;
  479.             /* 順に左→中央→右→中央→左へ移動 */
  480.             dx = dx_table[p->m_work2];
  481.             p->m_work2 = m_work_table[p->m_work2];    /* 移動方向 */
  482.  
  483.             /* player->y は乱数の種として使用しています */
  484.             if (SHORT_LY < 64)
  485.                 dy = (((unsigned short) rndtable[(player->y) & 0xff]) / 4 + 32);
  486.             else
  487.                 dy = 48;
  488.             /* 移動方向を設定 */
  489.             SubEnemyMoveToInit (p, dx, dy, SPEED_1, SPEED_1N);
  490.         } else {
  491.             /* 設定値に従って移動 */
  492.             if (SubEnemyMoveTo (p) < 0)
  493.                 p->m_work3 = 0;        /* 移動方向再設定 */
  494.         }
  495.  
  496.  
  497.         /* 次に攻撃処理 */
  498.  
  499.         /* 自機拘束弾 */
  500. #define SPEED_SHOT_5_2        22
  501. #define SPEED_SHOT_5_2_1    14
  502.         if (p->s_work2++ > 3) {
  503.             unsigned char a = psearch (p->x, p->y);
  504.             p->s_work2 = 0;
  505.             EshotAlloc (ESHOT_NRG03, SHORT_LX, SHORT_LY, SPEED_SHOT_5_2, a - 16, 0);
  506.             EshotAlloc (ESHOT_NRG03, SHORT_LX, SHORT_LY, SPEED_SHOT_5_2, a + 16, 0);
  507.             SoundSetSE (SE_ESHOT);    /* 敵ショット音 */
  508.             if (p->s_work3++ > 110) {
  509.                 p->s_work = 0;    /* 最初に戻る */
  510.                 p->s_work3 = 0;
  511.             } else {
  512.                 EshotAlloc (ESHOT_NRG24N, SHORT_LX, SHORT_LY + 16, SPEED_SHOT_5_2_1 + 2, (rndtable[p->s_work3] & 31) - 16 + psearch (p->x, p->y), 0);
  513.             }
  514.         }
  515.         break;
  516.  
  517.         /* 時間切れ撤退 */
  518.     case 7:
  519.         switch (p->m_work2) {
  520.         case 0:
  521.             if (SubEnemyMoveTo (p) < 0) {    /* 止まるまで待つ */
  522.                 p->m_work2++;
  523.                 SubEnemyMoveToInit (p, p->x, -128, SPEED_3, SPEED_3N);
  524.             }
  525.             break;
  526.         case 1:
  527.             if (SubEnemyMoveTo (p) < 0) {    /* 止まるまで待つ */
  528.                 return (-1);    /* 消去 */
  529.             }
  530.             break;
  531.         }
  532.         break;
  533.  
  534.         /* 死んだ */
  535.     case MOVE_DEATH:
  536.         switch (p->m_work2) {
  537.         case 0:
  538.             if (SubEnemyMoveToAbort (p) < 0) {    /* 止まるまで待つ */
  539.                 p->m_work2++;
  540.                 p->m_work3 = 0;
  541.                 p->m_work4 = 0;
  542.                 /* 当たり判定を無くす */
  543.                 p->hit_sx = p->hit_sy = 0;
  544.                 if (!eshot_erase)
  545.                     eshot_erase = ESHOT_ERASE;    /* 弾消し */
  546.             }
  547.             break;
  548.         case 1:
  549.             if (p->m_work3++ > 3) {
  550.                 p->m_work3 = 0;
  551.                 p->m_work4++;
  552.                 if (p->m_work4 < 15) {
  553.                     signed short x, y;
  554.                     x = rndtable[(p->timer) & 0xff ^ 0x55] - 128;
  555.                     y = rndtable[(p->timer) & 0xff ^ 0xaa] - 128;
  556.                     /* p->timer は乱数の種として使用しています */
  557.                     EffectAlloc (EFFECT_EXPL, 0, x / 2 + p->x, y / 4 + p->y + 16);    /* 爆発パターンを出現させる */
  558.                     SoundSetSE (SE_EXPL_M);        /* 中ボス爆発音 */
  559.                 }
  560.                 if (p->m_work4 > 20) {
  561.                     short h;
  562.                     for (h = 0; h < 6; h++) {
  563.                         EffectAlloc (EFFECT_EXPL, 0,
  564.                                  (signed short) ((rndtable[h] - 128) / 2) + p->x,
  565.                                  (signed short) ((rndtable[h + 1] - 128) / 4) + p->y + 16);
  566.                     }
  567.                     SoundSetSE (SE_EXPL_L);        /* ボスキャラ爆発音 */
  568.                     EffectAlloc (EFFECT_POINTS, POINTS_10000, p->x, p->y);    /* 得点を出現させる */
  569. //                  EffectAlloc (EFFECT_HAHEN, 0, p->x, p->y);
  570.  
  571.                     return (-1);    /* 消去 */
  572.                 }
  573.             }
  574.             break;
  575.         }
  576.     default:
  577.         break;
  578.     }
  579.  
  580.  
  581.     /* もし前回ダメージを受けたなら */
  582.     if (p->damage) {
  583.         p->hp -= p->damage;
  584.         p->damage = 0;
  585.         SoundSetSE (SE_DAMAGE);        /* 敵ダメージ音 */
  586.  
  587.         /* 白(or赤)フラッシュ処理 */
  588.         if (p->info == (PALET_MAIN | PRIORITY_BOSS)) {
  589.             if (p->hp < HP_PALET_RED)
  590.                 p->info = PALET_RED | PRIORITY_BOSS;
  591.             else
  592.                 p->info = PALET_DAMAGE | PRIORITY_BOSS;
  593.         } else {
  594.             p->info = PALET_MAIN | PRIORITY_BOSS;
  595.         }
  596.  
  597.         /* 定期的に刺さったショットを抜く */
  598.         if ((p->m_work5++ > TIME_SHOT_ERASE) && (p->shot)) {
  599.             p->shot->status = SHOT_STATUS_NON;
  600.             p->m_work5 = 0;
  601.         }
  602.         /* 耐久力が0以下なら消去 */
  603.         if (p->hp <= 0) {
  604.             p->m_work = MOVE_DEATH;
  605.             p->m_work2 = 0;
  606.             /* 刺さったショットの処理 */
  607.             if (p->shot)
  608.                 p->shot->status = SHOT_STATUS_NON;
  609.         }
  610.     } else {
  611.         /* 耐久力が少なくなったら赤フラッシュ */
  612.         if ((p->flash++ > TIMER_FLASH_RED) && (p->hp < HP_2)) {
  613.             p->info = PALET_RED | PRIORITY_BOSS;
  614.             if (p->flash > TIMER_FLASH_NORMAL)
  615.                 p->flash = 0;
  616.         } else {
  617.             p->info = PALET_MAIN | PRIORITY_BOSS;
  618.         }
  619.         p->m_work5 = 0;
  620.     }
  621.     xobj_set_st (p);
  622.  
  623.  
  624.     /* コアの表示 */
  625.     p->core_x = p->x - 8;    /* コアの中心は (-8,-8) ドットずれる */
  626.     p->core_y = p->y - 8;
  627.     xsp_set_st (&(p->core_x));
  628.     /* コア2つ目 */
  629.     p->core_x = p->x - 8;    /* コアの中心は (-8,+8) ドットずれる */
  630.     p->core_y = p->y + 8;
  631.     xsp_set_st (&(p->core_x));
  632.  
  633.     return (0);
  634. }
  635.  
  636.  
  637.  
  638. /* 消去ルーチン */
  639. static void EnemyFreeLBoss01 (ENEMY * p)
  640. {
  641.     /* 刺さったショットの処理 */
  642.     if ((p->shot) && (p->shot->enemy) && (p->shot->enemy == p))
  643.         p->shot->status = SHOT_STATUS_NON;
  644.  
  645.     player->game_over = GAME_COMPLETE;    /* ボスが消えたらゲーム終了 */
  646. }
  647.